package networkSimulation.simulation.social

import framework._
import monitor.FriendshipMonitor
import networkSimulation.visualisation.gui.VisualUIFrame
import simulation.SocialGraph
import util.Random
import networkSimulation.framework.UndirectedGraph
import java.lang.reflect.Method
import java.io.IOException

/**
 * Runnable class for a SocialGraph simulation
 *
 * @author  Tim Caljé
 *          Jeroen De Raedt
 *          Jorick Van Aken
 */
object Run {

  /**
   * Create and start the simulation
   *
   * - create a graph
   * - create a simulation with graph
   * - start the simulation
   */
  def main(args: Array[String]) {
    try {
      val graph = createGraph(20)
      val socialGraph = new SocialGraph(graph)
      var outputPath = "out\\"
      var socialMonitor = new FriendshipMonitor[Method, SocialGraph#Pub]("Social monitor", graph)
      socialGraph.subscribe(socialMonitor)
      socialGraph.startSimulation(5,outputPath)
      new VisualUIFrame(outputPath)
      new VisualUIFrame(outputPath+"graph")
    } catch {
      case e: IllegalArgumentException => println(e.getMessage)
      case e: IllegalStateException    => println("Illegal state exception: " + e.getMessage)
      case e: IOException              => println("IO exception: " + e.getMessage)
      case e: NullPointerException     => println("NullPointerException: " + e.getMessage)
      case e: Exception                => println("Unknown error: " + e.getMessage)
    }
  }

  /**
   * Create a graph.
  */
  private def createGraph(numberNodes:Int) : UndirectedGraph[Person,Friendship[Person]] = {

    val graph = new UndirectedGraph[Person,Friendship[Person]]

    for (i <- 0 until numberNodes){
      val p1 = new Person("p" + i)
      graph.addNode(p1)
    }

    for (i <- 0 until (numberNodes*2)){
      val p1 = graph.nodes.apply(new Random().nextInt(numberNodes-1))
      val p2 = graph.nodes.apply(new Random().nextInt(numberNodes-1))
      if (!p1.equals(p2)){
        val rnd = new Random().nextInt(4)
        if (rnd == 1) graph.addEdge(new FootBall(p1,p2))
        if (rnd == 2) graph.addEdge(new School(p1,p2))
        if (rnd == 3) graph.addEdge(new GayCommunity(p1,p2))
      }
    }

    graph
  }

}